// 文件: src/utils/downloadHelper.js

import apiClient from '@/api';
import { ElMessage, ElNotification } from 'element-plus';
import JSZip from 'jszip';
import { saveAs } from 'file-saver';

// ========【新增：一个无新标签页的、可复用的下载触发器】========
/**
 * 通过编程方式创建一个隐藏的<a>标签来触发下载，避免打开新窗口。
 * @param {string} url - 完整的下载链接。
 * @param {string} filename - 期望保存的文件名。
 */
const triggerDownload = (url, filename) => {
    // 1. 创建一个隐藏的 a 标签
    const link = document.createElement('a');
    link.href = url;

    // 2. 添加 download 属性，浏览器会下载而不是导航
    link.setAttribute('download', filename || 'download');

    // 3. 将其附加到DOM，模拟点击，然后移除
    document.body.appendChild(link);
    link.click();
    document.body.removeChild(link);
};

// export const secureDownloadItem = async (bucketName, item) => {
//     if (!bucketName || !item || !item.name || !item.type) {
//         ElMessage.error('下载信息不完整');
//         return;
//     }

//     try {
//         // 1. 调用后端接口，发送【正确的】JSON载荷
//         const response = await apiClient.post('/api/v1/generate-download-link', {
//             bucket_name: bucketName,
//             item: {
//                 name: item.name,
//                 type: item.type,
//             },
//             expires_in: 300, // 或根据需要传递
//         });

//         const relativeUrl = response.data.download_url;

//         if (relativeUrl) {
//             const fullUrl = `${apiClient.defaults.baseURL}${relativeUrl}`;
//             const filename = item.name.split('/').pop() || item.name;
//             const downloadFilename = item.type === 'folder' ? `${filename}.zip` : filename;

//             triggerDownload(fullUrl, downloadFilename);
//         } else {
//             throw new Error('后端未返回有效的下载链接');
//         }

//     } catch (error) {
//         console.error(`下载项目 ${item.name} 失败:`, error);
//         ElMessage.error('准备下载失败，请重试');
//     }
// };


// ========【修改：升级单个文件下载函数】========
export const secureDownloadFile = async (bucketName, objectKey, expiresIn = 300) => {
    if (!bucketName || !objectKey) {
        ElMessage.error('缺少文件信息，无法下载');
        return;
    }

    try {
        const response = await apiClient.post('/api/v1/generate-download-link', {
            bucket_name: bucketName,
            path: objectKey,
            expires_in: expiresIn,
        });

        const relativeUrl = response.data.download_url;

        if (relativeUrl) {
            const fullUrl = `${apiClient.defaults.baseURL}${relativeUrl}`;

            // 从 objectKey 中提取基本文件名
            const filename = objectKey.split('/').pop();

            // 【核心】调用我们新的下载触发器，而不是 window.open
            triggerDownload(fullUrl, filename);

        } else {
            throw new Error('后端未返回有效的下载链接');
        }

    } catch (error) {
        console.error(`下载文件 ${objectKey} 失败:`, error);
        ElMessage.error('准备文件下载失败，请重试');
    }
};


// ========【修改：升级文件夹下载函数】========
export const secureDownloadFolder = async (bucketName, folderKey, expiresIn = 3600) => {
    if (!bucketName || !folderKey) {
        ElMessage.error('缺少文件夹信息，无法下载');
        return;
    }

    try {
        const response = await apiClient.post('/api/v1/generate-folder-download-link', {
            bucket_name: bucketName,
            path: folderKey,
            expires_in: expiresIn,
        });

        const relativeUrl = response.data.download_url;

        if (relativeUrl) {
            const fullUrl = `${apiClient.defaults.baseURL}${relativeUrl}`;

            // 从 folderKey 中提取文件夹名，并添加 .zip 后缀
            const folderName = folderKey.replace(/\/$/, '').split('/').pop() || bucketName;

            // 【核心】调用我们新的下载触发器，而不是 window.open
            triggerDownload(fullUrl, `${folderName}.zip`);

        } else {
            throw new Error('后端未返回有效的下载链接');
        }

    } catch (error) {
        console.error(`下载文件夹 ${folderKey} 失败:`, error);
        ElMessage.error('准备文件夹下载失败，请重试');
    }
};

/**
 * 安全地批量下载文件和文件夹。
 * @param {string} bucketName - 桶名。
 * @param {Array} items - 选中的项目列表，每个项目是 { name: "...", type: "..." }。
 */
// export const secureBatchDownload = async (bucketName, items) => {
//     if (!items || items.length === 0) {
//         ElMessage.warning('没有选中任何项目');
//         return;
//     }

//     const notification = ElNotification({
//         title: '准备下载',
//         message: '正在获取安全链接...',
//         type: 'info',
//         duration: 0, // 持续显示直到手动关闭
//     });

//     try {
//         // 1. 一次性从后端获取所有文件的安全下载链接
//         const response = await apiClient.post('/api/v1/generate-batch-download-links', {
//             bucket_name: bucketName,
//             items: items,
//         });

//         const links = response.data.links;
//         if (!links || links.length === 0) {
//             ElMessage.error('没有可下载的文件');
//             notification.close();
//             return;
//         }

//         notification.message = `正在下载 ${links.length} 个文件并打包...`;

//         const zip = new JSZip();
//         const promises = links.map(linkInfo => {
//             const fullUrl = `${apiClient.defaults.baseURL}${linkInfo.url}`;
//             return fetch(fullUrl)
//                 .then(res => {
//                     if (!res.ok) throw new Error(`下载文件 ${linkInfo.key} 失败`);
//                     return res.blob();
//                 })
//                 .then(blob => {
//                     // 保留原始的目录结构
//                     zip.file(linkInfo.key, blob);
//                 });
//         });

//         await Promise.all(promises);

//         notification.message = '正在生成ZIP文件...';

//         const content = await zip.generateAsync({ type: 'blob' });
//         saveAs(content, `${bucketName}-batch-download.zip`);

//         notification.close();
//         ElNotification({
//             title: '下载完成',
//             message: `已成功打包 ${links.length} 个文件。`,
//             type: 'success',
//         });

//     } catch (error) {
//         console.error('批量下载失败:', error);
//         notification.close();
//         ElMessage.error('批量下载过程中发生错误，请重试');
//     }
// };

/**
 * 判断一个文件是否可能是S3/OSS自动生成的日志文件。
 * @param {string} bucketName - 所在的存储桶名称。
 * @param {string} key - 文件的完整Key。
 * @returns {boolean}
 */
const isLikelyLogFile = (bucketName, key) => {
    if (!bucketName || !key) return false;

    // 条件1: 桶名包含 'log' 或 'logging' (宽松判断)
    const isLoggingBucket = bucketName.toLowerCase().includes('log');

    // 条件2: 文件名符合S3日志格式 (YYYY-MM-DD-HH-MM-SS-UNIQUEID)
    // 正则表达式解释:
    // \d{4}-\d{2}-\d{2}  -> 匹配 YYYY-MM-DD
    // -\d{2}-\d{2}-\d{2}  -> 匹配 -HH-MM-SS
    // -[A-Z0-9]+        -> 匹配 -后面跟着一串大写字母和数字的唯一ID
    const logFilePattern = /^\d{4}-\d{2}-\d{2}-\d{2}:\d{2}:\d{2}\.\d+-[a-zA-Z0-9]+$/;

    // 从key中提取基本文件名
    const basename = key.split('/').pop();
    const matchesPattern = logFilePattern.test(basename);

    // 两个条件同时满足
    return isLoggingBucket && matchesPattern;
};

/**
 * 智能下载单个项目（文件或文件夹）。
 * 它会自动判断是否为日志文件，并调用相应的后端API。
 * @param {string} bucketName - 桶名称。
 * @param {object} item - 要下载的项目对象 { name: "...", type: "..." }。
 * @param {number} expiresIn - 预签名URL的有效期（秒）。
 */
export const secureDownloadItem = async (bucketName, item, expiresIn = 300) => {
    if (!bucketName || !item || !item.name || !item.type) {
        ElMessage.error('下载信息不完整');
        return;
    }

    // --- 【核心决策逻辑】 ---
    if (item.type === 'file' && isLikelyLogFile(bucketName, item.name)) {
        // **场景A: 这是一个日志文件，调用专门的日志下载API**
        console.log(`[Downloader] Identified ${item.name} as a log file. Using log download API.`);
        const downloadUrl = `${apiClient.defaults.baseURL}/api/v1/buckets/${bucketName}/logs/download?key=${encodeURIComponent(item.name)}`;
        window.location.href = downloadUrl; // 直接通过浏览器原生下载
        return;
    }

    // **场景B: 这是普通文件或文件夹，走原来的预签名链接流程**
    console.log(`[Downloader] Identified ${item.name} as a regular item. Using presigned URL.`);
    try {
        const response = await apiClient.post('/api/v1/generate-download-link', {
            bucket_name: bucketName,
            item: { name: item.name, type: item.type },
            expires_in: expiresIn,
        });

        const relativeUrl = response.data.download_url;
        if (relativeUrl) {
            const fullUrl = `${apiClient.defaults.baseURL}${relativeUrl}`;
            window.open(fullUrl, '_blank'); // 普通下载可以用新标签页打开，体验更佳
        } else {
            throw new Error('后端未返回有效的下载链接');
        }
    } catch (error) {
        console.error(`下载项目 ${item.name} 失败:`, error);
        ElMessage.error('准备下载失败，请重试');
    }
};

/**
 * 智能批量下载项目。
 * 它会判断选中的文件是否全部为日志文件，并选择最优的下载策略。
 * @param {string} bucketName - 桶名称。
 * @param {Array} items - 选中的项目列表，每个项目是 { name: "...", type: "..." }。
 */
export const secureBatchDownload = async (bucketName, items) => {
    if (!items || items.length === 0) {
        ElMessage.warning('没有选中任何项目');
        return;
    }

    const notification = ElNotification({
        title: '准备下载',
        message: '正在获取安全链接...',
        type: 'info',
        duration: 0, // 持续显示直到手动关闭
    });

    // --- 【核心决策逻辑】 ---
    // 条件：所有选中的项目都必须是文件，并且都符合日志文件的特征
    const allAreLogFiles = items.every(item =>
        item.type === 'file' && isLikelyLogFile(bucketName, item.name)
    );

    const selectedKeys = items.map(item => item.name);

    if (allAreLogFiles) {
        // **场景A: 所有选中的都是日志文件，调用后端的日志批量打包API**
        console.log(`[Downloader] Identified all ${items.length} items as log files. Using backend batch log download.`);
        try {
            const response = await apiClient.post(
                `/api/v1/buckets/${bucketName}/logs/batch-download`,
                { keys: selectedKeys },
                { responseType: 'blob' }
            );
            const blob = new Blob([response.data], { type: 'application/zip' });

            const contentDisposition = response.headers['content-disposition'];
            let filename = `${bucketName}-logs.zip`;
            if (contentDisposition) {
                const filenameMatch = contentDisposition.match(/filename\*?=(?:UTF-8'')?([^;]+)/);
                if (filenameMatch && filenameMatch[1]) filename = decodeURIComponent(filenameMatch[1].replace(/"/g, ''));
            }
            saveAs(blob, filename);

        } catch (error) {
            console.error('批量下载日志失败:', error);
            ElMessage.error('批量下载日志失败');
        }

    } else {
        // **场景B: 包含普通文件或文件夹，继续走原来的前端打包逻辑**
        console.log(`[Downloader] Selection contains mixed items. Using frontend batch download.`);
        // (此处的代码是您之前已有的前端打包逻辑，保持不变)
        try {
            const response = await apiClient.post('/api/v1/generate-batch-download-links', {
                bucket_name: bucketName,
                items: items, // 发送完整的item对象
            });

            const links = response.data.links;
            if (!links || links.length === 0) {
                ElMessage.error('没有可下载的文件');
                notification.close();
                return;
            }

            notification.message = `正在下载 ${links.length} 个文件并打包...`;

            const zip = new JSZip();
            const promises = links.map(linkInfo => {
                const fullUrl = `${apiClient.defaults.baseURL}${linkInfo.url}`;
                return fetch(fullUrl)
                    .then(res => {
                        if (!res.ok) throw new Error(`下载文件 ${linkInfo.key} 失败`);
                        return res.blob();
                    })
                    .then(blob => {
                        // 保留原始的目录结构
                        zip.file(linkInfo.key, blob);
                    });
            });

            await Promise.all(promises);

            notification.message = '正在生成ZIP文件...';

            const content = await zip.generateAsync({ type: 'blob' });
            saveAs(content, `${bucketName}-batch-download.zip`);

            notification.close();
            ElNotification({
                title: '下载完成',
                message: `已成功打包 ${links.length} 个文件。`,
                type: 'success',
            });
            // ... (后续的前端 JSZip 打包逻辑) ...
            // 为简洁起见，此处省略，您只需确保此处的逻辑是您之前的前端打包代码即可
            console.log("此处应执行前端JSZip打包逻辑...");
            // ElMessage.info("正在通过前端打包下载...")

        } catch (error) {
            console.error('批量下载失败:', error);
            ElMessage.error('批量下载过程中发生错误，请重试');
        }
    }
};